package pl.smath.renderer.model;

import gwt.g2d.client.graphics.Surface;
import pl.smath.renderer.renderer.TermRendererException;
import pl.smath.renderer.utils.Cursor;
import pl.smath.renderer.utils.InteractionSocket;
import pl.smath.renderer.utils.Rectangle;

import com.google.gwt.user.client.ui.RootPanel;

public class StringView extends AbstractMultiView {

	public StringView(String text) {
		super(text);
		//char c = text.charAt(0);
		//int i = (int)c;
	}

	/**
	 * render text at the current position
	 * @param canvas
	 */
	@Override
	public void render(Surface canvas, InteractionSocket socket) throws TermRendererException {
		if ((this.getFont() == null)||(this.getFontHeight() == null)) {
			throw new TermRendererException();
		}
		canvas.setFont(this.getFont());
		
		Cursor cursor = new Cursor(this.getCursor().getX(), this.getCursor().getY() - this.getBaselineOffset());
		
		Double minusWidth = this.minusSign.getWidth();
		
		if (getText().equals("")){
			for (int i = 0; i < this.views.size(); i++) {
				View view = this.views.elementAt(i);
				view.render(canvas, socket);
				cursor.setX(view.getX() + view.getWidth());

			}	
		} else {
			canvas.fillText(getText(), cursor.getX(), cursor.getY());
		}
		

		if (this.isNegative()) {
			canvas.fillText(")", cursor.getX(), cursor.getY());
		}
	}
	

	/**
	 * set the position on canvas to render
	 * @param Cursor
	 */
	@Override
	public void setCursor(Cursor cursor) {
		//if (this.getCursor()==null) {
			super.setCursor(new Cursor(cursor.getX(), cursor.getY()));
			
			Surface canvas = new Surface();
			RootPanel.get().add(canvas);
			canvas.setFont(this.getFont());
			
			Double minusWidth = this.minusSign.getWidth();
			
			Cursor toSet = new Cursor(cursor.getX(), cursor.getY() - this.getBaselineOffset());

			if (getText().equals("")){
				for (int i = 0; i < this.views.size(); i++) {
					View view = this.views.elementAt(i);
					
					view.setCursor(new Cursor(toSet.getX(), toSet.getY() + view.getBaselineOffset()));
					
					toSet.setX(toSet.getX() + view.getWidth());
				} 
			}
			
			RootPanel.get().remove(canvas);
		
	}
	
	/**
	 * @param font the font to set
	 */
	@Override
	public void setFont(String font) {
		if (font.indexOf("px")!=-1) {
			this.setFontHeight(new Double(font.substring(0, font.indexOf("px"))));
			this.font = font.substring(font.indexOf("px ")+3);
			this.minusSign.setFont(this.font, this.getFontHeight());

			for (View view : this.views) {
				view.setFont(font);
			}
			
			update();
		} else {
			this.setFontHeight(null);
			this.font = null;
		}
	}
	
	/**
	 * updates the view after changes
	 */
	@Override
	public void update() {
		
		Surface surface = new Surface();
		RootPanel.get().add(surface);
		surface.setFont(this.getFont());
		
		Double bracketsWidth = surface.measureText("()");
		Double minusWidth = this.minusSign.getWidth();
		Double maxOverBaseline = 0d;
		
		this.setRectangle(new Rectangle());
		this.setBaselineOffset(0d);
		
		if (getText().equals("")){
			for (int i = 0; i < this.views.size(); i++) {
				View view = this.views.elementAt(i);
				this.setWidth(this.getWidth() + view.getWidth());
				
				Double overBaseline = 0d;
				
				this.setBaselineOffset(Math.max(this.getBaselineOffset(), view.getBaselineOffset()));
				overBaseline = view.getHeight() - view.getBaselineOffset();
	
				maxOverBaseline = Math.max(maxOverBaseline, overBaseline);
			}
			this.setHeight(maxOverBaseline + this.getBaselineOffset());
		} else {
			this.setWidth(surface.measureText(getText()));
			this.setHeight(getFontHeight());
		}
		
		
		RootPanel.get().remove(surface);
	}
	
}
